﻿using System.IO;
using System.Linq;
using Dokan;
using System;

namespace CueMounter.DokanStructure
{
	partial class DokanDirectoryOperations
	{
		public int CreateFile_Create(string[] path, FileAccess access, FileShare share, FileOptions options, DokanFileInfo info)
		{
			string[] dirPath = path.Take(path.Length - 1).ToArray();
			string fileName = path[path.Length-1];
			foreach(var root in RootDirectories)
			{
				DokanDirectory dir = root.GetDirectory(dirPath);
				if(dir != null)
				{
					if(dir.GetDirectory(fileName) != null)
					{
						info.IsDirectory = true;
						return -DokanNet.ERROR_ALREADY_EXISTS;
					}
					if(dir.GetFile(fileName) != null)
					{
						return DokanNet.DOKAN_SUCCESS;
					}
					try
					{
						dir.CreateFile(fileName);
						return DokanNet.DOKAN_SUCCESS;
					}
					catch
					{
					}
				}
			}
			return -DokanNet.ERROR_ACCESS_DENIED;
		}

		public int CreateFile_CreateNew(string[] path, FileAccess access, FileShare share, FileOptions options, DokanFileInfo info)
		{
			string[] dirPath = path.Take(path.Length - 1).ToArray();
			string fileName = path[path.Length - 1];
			foreach(var root in RootDirectories)
			{
				DokanDirectory dir = root.GetDirectory(dirPath);
				if(dir != null)
				{
					if(dir.GetDirectory(fileName) != null)
					{
						info.IsDirectory = true;
						return -DokanNet.ERROR_ALREADY_EXISTS;
					}
					if(dir.GetFile(fileName) != null)
					{
						return -DokanNet.ERROR_ALREADY_EXISTS;
					}
					try
					{
						dir.CreateFile(fileName);
						return DokanNet.DOKAN_SUCCESS;
					}
					catch
					{
					}
				}
			}
			return -DokanNet.ERROR_ACCESS_DENIED;
		}

		public int CreateFile_Open(string[] path, FileAccess access, FileShare share, FileOptions options, DokanFileInfo info)
		{
			string[] dirPath = path.Take(path.Length - 1).ToArray();
			string fileName = path[path.Length - 1];
			foreach(var root in RootDirectories)
			{
				DokanDirectory dir = root.GetDirectory(dirPath);
				if(dir != null)
				{
					if(dir.GetFile(fileName) != null)
					{
						return DokanNet.DOKAN_SUCCESS;
					}
					if(dir.GetDirectory(fileName) != null)
					{
						info.IsDirectory = true;
						return DokanNet.DOKAN_SUCCESS;
					}
				}
			}
			return -DokanNet.ERROR_FILE_NOT_FOUND;
		}

		public int CreateFile_OpenOrCreate(string[] path, FileAccess access, FileShare share, FileOptions options, DokanFileInfo info)
		{
			string[] dirPath = path.Take(path.Length - 1).ToArray();
			string fileName = path[path.Length - 1];
			foreach(var root in RootDirectories)
			{
				DokanDirectory dir = root.GetDirectory(dirPath);
				if(dir != null)
				{
					if(dir.GetFile(fileName) != null)
					{
						return DokanNet.DOKAN_SUCCESS;
					}
					if(dir.GetDirectory(fileName) != null)
					{
						info.IsDirectory = true;
						return DokanNet.ERROR_ALREADY_EXISTS;
					}
					try
					{
						dir.CreateFile(fileName);
						return DokanNet.DOKAN_SUCCESS;
					}
					catch
					{
					}
				}
			}
			return -DokanNet.ERROR_FILE_NOT_FOUND;
		}

		public int CreateFile_Truncate(string[] path, FileAccess access, FileShare share, FileOptions options, DokanFileInfo info)
		{
			string[] dirPath = path.Take(path.Length - 1).ToArray();
			string fileName = path[path.Length - 1];
			foreach(var root in RootDirectories)
			{
				DokanDirectory dir = root.GetDirectory(dirPath);
				if(dir != null)
				{
					if(dir.GetFile(fileName) != null)
					{
						return DokanNet.DOKAN_SUCCESS;
					}
					if(dir.GetDirectory(fileName) != null)
					{
						info.IsDirectory = true;
						return DokanNet.ERROR_ALREADY_EXISTS;
					}
					try
					{
						dir.CreateFile(fileName);
						return DokanNet.DOKAN_SUCCESS;
					}
					catch
					{
					}
				}
			}
			return -DokanNet.ERROR_FILE_NOT_FOUND;
		}

		public int CreateFile(string filename, FileAccess access, FileShare share, FileMode mode, FileOptions options, DokanFileInfo info)
		{
			string[] path = GetPath(filename);
			if(path.Length == 0)
			{
				return DokanNet.DOKAN_SUCCESS;
			}

			switch(mode)
			{
				case FileMode.Append:
					return CreateFile_Create(path, access, share, options, info);
				case FileMode.Create:
					return CreateFile_Create(path, access, share, options, info);
				case FileMode.CreateNew:
					return CreateFile_CreateNew(path, access, share, options, info);
				case FileMode.Open:
					return CreateFile_Open(path, access, share, options, info);
				case FileMode.OpenOrCreate:
					return CreateFile_OpenOrCreate(path, access, share, options, info);
				case FileMode.Truncate:
					return CreateFile_Truncate(path, access, share, options, info);
				default:
					throw new NotImplementedException();
			}
		}
	}
}
